package com.android.support.lib.universal.util;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.GridView;
import android.widget.TextView;

import java.lang.reflect.Field;

/**
 * UI适配工具。
 * 使用说明：
 * UtilProportion.getInstance(this).reflection(this.getClass(), this);//通过反射来自动适配当前所有View控件(不太可靠)
 * 或(非常可靠)：
 * UtilProportion.getInstance(this).adapterTextView((TextView) findViewById(R.id.textView));//通过控件ID自主适配
 * 退出时建议调用：onDestroy()
 * Created by 彭治铭 on 2016/10/10.
 */

public class UtilProportion {
    private static UtilProportion utilProportion;

    private float textProportion;//文字比例大小
    private float horizontalProportion;//水平比例大小
    private float verticalProportion;//垂直比例大小
    private float density;//当前设备dpi密度值比例
    private Boolean ignore = false;//是否忽悠比例缩放

    public static UtilProportion getInstance(Activity activity) {
        if (utilProportion == null) {
            utilProportion = new UtilProportion(activity);
        }
        return utilProportion;
    }
    //兼容Activity和Context
    public static UtilProportion getInstance(Context context) {
        if (utilProportion == null) {
            utilProportion = new UtilProportion(context);
        }
        return utilProportion;
    }

    float widthPixels = 1280;//水平分辨率
    float heightPixels = 720;//垂直分辨率 1920x1080作为主流标准。比例为16:9

    private UtilProportion(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        density = displayMetrics.density;
        horizontalProportion = displayMetrics.widthPixels / widthPixels;
        //垂直比例,文本比例,都以水平比例为标准.屏幕适配的比例一定要保持一致。
        verticalProportion = horizontalProportion;
        textProportion = horizontalProportion;
        ignore();

//        Log.e("ui", "密度2：" + this.density);
//        Log.e("ui", "displayMetrics.widthPixels:" + displayMetrics.widthPixels + "\ndisplayMetrics.heightPixels:" + displayMetrics.heightPixels);
//        Log.e("ui", "horizontalProportion:\t" + horizontalProportion + "\tverticalProportion\t" + verticalProportion);
    }

    private UtilProportion(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        density = displayMetrics.density;
        horizontalProportion = displayMetrics.widthPixels / widthPixels;
        //垂直比例,文本比例,都以水平比例为标准.屏幕适配的比例一定要保持一致。
        verticalProportion = horizontalProportion;
        textProportion = horizontalProportion;
        ignore();

//以下方法，不太可靠。舍弃。
//        this.verticalProportion = displayMetrics.heightPixels / heightPixels;
//        this.textProportion = horizontalProportion > verticalProportion ? horizontalProportion : verticalProportion;
//
//        if (Math.abs(horizontalProportion - verticalProportion) > 0.5) {
//            this.textProportion = textProportion - 0.2f;
//            this.verticalProportion = horizontalProportion > verticalProportion ? horizontalProportion : verticalProportion - 0.35f;
//        } else if (Math.abs(horizontalProportion - verticalProportion) > 0.3) {
//            this.textProportion = textProportion - 0.1f;
//            this.verticalProportion = horizontalProportion > verticalProportion ? horizontalProportion : verticalProportion - 0.1f;
//        }
//
//        Log.e("ui", "密度：" + this.density);
//        Log.e("ui", "displayMetrics.widthPixels:" + displayMetrics.widthPixels + "\ndisplayMetrics.heightPixels:" + displayMetrics.heightPixels);
//        Log.e("ui", "horizontalProportion:\t" + horizontalProportion + "\tverticalProportion\t" + verticalProportion);

        displayMetrics = null;
    }

    private void ignore() {
        //防止比例为1的时候做多余的适配
        if (horizontalProportion > 0.99 && horizontalProportion < 1.01) {
            ignore = true;
        } else {
            ignore = false;
        }
//        Log.e("ui","ignore:\t"+ignore);
    }

    //自我销毁,退出应用时，建议调用
    public void onDestroy() {
        if (utilProportion != null) {
            utilProportion = null;
        }
    }

    //适配Bitmap
    public Bitmap adapterBitem(Bitmap src) {
        if (ignore) {
            return src;
        }
        Bitmap scaleBitmap = Bitmap.createScaledBitmap(src, (int) (src.getWidth() * horizontalProportion), (int) (src.getHeight() * verticalProportion), true);
        return scaleBitmap;
    }

    public void adapterView(View view) {
        if (ignore) {
            return;
        }
        try {
            ViewGroup.LayoutParams laParams = view
                    .getLayoutParams();

            if (laParams.width > 0) {
                //单位都是像素
                laParams.width = (int) (laParams.width * horizontalProportion);
            } else if (view.getBackground() != null) {
                laParams.width = (int) (view.getBackground().getIntrinsicWidth() * horizontalProportion);
            }
            if (laParams.height > 0) {
                laParams.height = (int) (laParams.height * verticalProportion);
            } else if (view.getBackground() != null) {
                laParams.height = (int) (view.getBackground().getIntrinsicHeight() * verticalProportion);
            }

            //这一句有没有都无所谓，因为laParams已经和View关联上。本来就是一体。赋值的是对象而不是值。所以是关联的。
            //所以这一句只是为了保险而且。
            view.setLayoutParams(laParams);
            adapterPadding(view);
            laParams = null;

//            Log.e("ui","执行了");
//            if(view.getBackground()!=null){
//                Drawable drawable=view.getBackground();
//                Bitmap bitmap=((BitmapDrawable)view.getBackground()).getBitmap();
//                Log.e("ui","占用空间大小:"+(bitmap.getByteCount())/1024+"KB"+(bitmap.getByteCount())/1024/1024+"MB");
//
//            }

        } catch (Exception e) {
            Log.e("ui", "View:\t" + e.getMessage());
        }
    }

    public void adapterTextView(TextView textView) {
        if (ignore) {
            //Log.e("test","忽悠");
            return;
        }
        try {
            adapterView(textView);
            textView.setTextSize(textView.getTextSize() * textProportion / density);//除以density是将px转化为dp
        } catch (Exception e) {
            Log.e("ui", "TextView:\t" + e.getMessage());
        }
    }

    public void adapterButton(Button button) {
        if (ignore) {
            return;
        }
        try {
            adapterView(button);
            button.setTextSize(button.getTextSize() * textProportion / density);//px=dp*dpi/160=dp*density,所以dp=px/density
        } catch (Exception e) {
            Log.e("ui", "Button:\t" + e.getMessage());
        }
    }

    @SuppressLint("NewApi")
    public void adapterGridview(GridView gridView) {
        if (ignore) {
            return;
        }
        try {
            adapterView(gridView);
            //Log.e("test","水平间隙"+gridView.getHorizontalSpacing()+"\t垂直间隙"+gridView.getVerticalSpacing());
            //setVerticalSpacing参数是像素，只需要设置垂直间隙。水平间隙会根据item的宽度合理安排。不需要设置(设置了也无效)
            gridView.setVerticalSpacing((int) (gridView.getVerticalSpacing() * verticalProportion));
        } catch (Exception e) {
            Log.e("ui", "GridView:\t" + e.getMessage());
        }
    }

    public void adapterPadding(View view) {
        //单位为像素px(get和set都是PX)
        //Log.e("ui","padding\tleft:\t"+view.getPaddingLeft()+"\ttop:\t"+view.getPaddingTop()+"\tright:\t"+view.getPaddingRight()+"\tbottom:\t"+view.getPaddingBottom());
        view.setPadding((int) (view.getPaddingLeft() * horizontalProportion), (int) (view.getPaddingTop() * verticalProportion), (int) (view.getPaddingRight() * horizontalProportion), (int) (view.getPaddingBottom() * verticalProportion));
        //Log.e("ui","padding\tleft:\t"+view.getPaddingLeft()+"\ttop:\t"+view.getPaddingTop()+"\tright:\t"+view.getPaddingRight()+"\tbottom:\t"+view.getPaddingBottom());
    }

    /**
     * 通过反射来适配UI,测试时使用没问题。
     * 但是App签名打包后，运行会错误。可能是系统自动自带混淆，导致反射找不到变量名了。
     *
     * @param clazz  参数一 this.getClass()
     * @param entity 参数二 this
     */
    public void reflection(Class clazz, Object entity) {
        //Class<?> clazz = getClass();
        Field[] fields = clazz.getFields();//获取当前类所有的属性
        for (Field field : fields) {
            try {
                Object obj = field.get(entity);
                if (obj instanceof View) {//对属性进行过滤
                    //View view = (View) obj;//直接对view操作即可。无论是控件还是布局都继承View
                    //Log.e("ui", "属性" + field.getName());
                    if (obj instanceof Button) {//Button继承TextView，所有判断放在TextView前面
                        adapterButton((Button) obj);
                    } else if (obj instanceof TextView) {
                        adapterTextView((TextView) obj);
                    } else if (obj instanceof GridView) {
                        adapterGridview((GridView) obj);
                    } else {
                        adapterView((View) obj);
                    }
                    field = null;
                    obj = null;
                }
            } catch (Exception e) {
                Log.e("ui", "field:\t" + e.getMessage());
            }
        }
        fields = null;
        System.gc();
    }

    public float getTextProportion() {
        return textProportion;
    }

    public float getHorizontalProportion() {
        return horizontalProportion;
    }

    public float getVerticalProportion() {
        return verticalProportion;
    }

    public float getDensity() {
        return density;
    }
}
